package com.hifar.test.syncexport8357.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpServletRequest;

import com.hifar.test.entrust.constant.TestConsts;
import com.hifar.test.exportdetail8357.pojo.SysSyncExportDetail8357;
import com.hifar.test.exportdetail8357.service.ISysSyncExportDetail8357Service;
import com.hifar.test.exporttask.pojo.SysSyncExportTask;
import com.hifar.test.exporttask.service.ISysSyncExportTaskService;
import com.hifar.test.syncexport8357.pojo.SysSyncExport8357;
import com.hifar.test.syncexport8357.service.ISysSyncExport8357Service;
import com.hifar.test.syncimport8357.service.ISysSyncImport8357Service;
import com.hifar.test.synctable8357.pojo.SysInfoSyncTable8357;
import com.hifar.test.synctable8357.service.ISysInfoSyncTable8357Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hifar.abi.dc.dt.utils.DataTypeConst;
import com.hifar.abi.utils.minio.MinioCfgUtils;
import com.hifar.abi.utils.minio.MinioUtils;
import com.hifar.config.AsyncConfig;
import com.hifar.fw.json.JsonUtils;
import com.hifar.fw.utils.bean.BusiRequest;
import com.hifar.fw.utils.consts.SysConsts;
import com.hifar.fw.utils.exception.ServiceException;
import com.hifar.fw.utils.file.FileUtils;
import com.hifar.fw.utils.file.TextFileUtils;
import com.hifar.fw.utils.id.IdUtils;
import com.hifar.fw.utils.lang.DateUtils;
import com.hifar.fw.utils.lang.NumberUtils;
import com.hifar.fw.utils.lang.StringUtils;
import com.hifar.fw.utils.lang.UrlUtils;
import com.hifar.plat.baseModal.entityDTO.FileDTO;
import com.hifar.plat.baseModal.entityDTO.FileParamDTO;
import com.hifar.plat.baseModal.entityDTO.ZipFileDTO;
import com.hifar.plat.baseModal.pojo.BaseOssFiles;
import com.hifar.plat.baseModal.service.IBaseOssFilesService;
import com.hifar.plat.maindatasource.service.ICollectdbDataSourceService;
import com.hifar.plat.maindatasource.service.IMainDataSourceService;
import com.hifar.plat.officUtil.ExcelTemplateUtil;
import com.hifar.plat.util.AESUtils;
import com.hifar.plat.util.DataDealUtils;

import com.hifar.proj.syncexport.pojo.ColumnVo;

import com.hifar.sys.BusiResponse;
import com.hifar.sys.DataSourceProp;
import com.hifar.sys.MinioUtil;
import com.hifar.sys.PageResult;
import com.hifar.sys.RequestConver;
import com.hifar.sys.SystemLoginUser;
import com.hifar.sys.SystemUtil;

import io.minio.messages.Item;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.CompressionLevel;
import net.lingala.zip4j.model.enums.CompressionMethod;

/**
 * <p>
 * 双网同步-导出表 前端控制器 default
 * </p>
 *
 * @author wangkepeng
 * @since 2024-11-13 17:13:08
 */
@SuppressWarnings("all")
@RestController
@RequestMapping("/api/busi/test/sysSyncExport8357Controller")
@Api(tags = "双网同步-导出表功能")
@Slf4j
public class SysSyncExport8357Controller {
    //委托单需要同步的任务表
    public String ENTRUST_TASK_TABLE = "hf_env_gk_task";
    //需要同步的试验表
    public String ENTRUST_TEST_TABLE = "hf_env_test";

    @Autowired
    private ISysSyncExport8357Service sysSyncExport8357Service;

    @Autowired
    private IBaseOssFilesService baseOssFilesService;

    @Autowired
    private ISysSyncImport8357Service sysSyncImport8357Service;

    @Autowired
    private IMainDataSourceService mainDataSourceService;

    @Autowired
    private ISysSyncExportDetail8357Service sysSyncExportDetail8357Service;

    @Autowired
    private ISysInfoSyncTable8357Service sysInfoSyncTable8357Service;

    @Autowired
    private DataSourceProp dataSourceProp;

    @Autowired
    private DataSourceProp dataSourceCollect;

    @Autowired
    private AsyncConfig asynConfig;

    @Autowired
    private ISysSyncExportTaskService sysSyncExportTaskService;

    @Autowired
    private ICollectdbDataSourceService collectdbDataSourceService;

    @Value("${spring.datasource.dynamic.datasource.collectdb.url:''}")
    private String collectDBUrl;


    @PostMapping(value = "/list")
    @ApiOperation(value = "双网同步-导出表功能:分页查询列表")
    public BusiResponse list(HttpServletRequest request) {
        Map<String, Object> pageInfo = RequestConver.getPageInfo(request);


        String dbType = mainDataSourceService.getDbType();
        String formateString = "";
        if (dbType.equals("dameng")) {
            formateString = "yyyy-mm-dd";
        } else if (dbType.equals("mysql")) {
            formateString = "%Y-%m-%d";
        } else {
            formateString = "%Y-%m-%d";
        }


        QueryWrapper<SysSyncExport8357> queryWrapper = RequestConver.getPostParamRangeDate(pageInfo, formateString);

        queryWrapper.orderByDesc("create_time");
        queryWrapper.in("secret_level", SystemLoginUser.dataSecretSet);
        if (queryWrapper != null && pageInfo.size() > 0) {
            Page<SysSyncExport8357> page = new Page<>((Integer) pageInfo.get("pageNo"), (Integer) pageInfo.get("pageSize"));
            Page<SysSyncExport8357> page1 = sysSyncExport8357Service.page(page, queryWrapper);
            page1.getRecords().forEach(item -> {
                String id = item.getId();
                BusiRequest requestParam = new BusiRequest();
                requestParam.getExt().put("tenantId", SysConsts.TENANT_ID);
                List<Map<String, Object>> dataList = MinioUtils.listFilesByRefId(requestParam, id);
                item.setFileList(dataList);

                try {
                    if (!dataList.isEmpty()) {
                        Map<String, Object> stringObjectMap = dataList.get(0);
                        String bucketPre = StringUtils.trimNull(stringObjectMap.get("bucketPre"));
                        String bucketName = StringUtils.trimNull(stringObjectMap.get("bucketName"));
                        String downloadPath = StringUtils.trimNull(stringObjectMap.get("downloadPath"));
                        item.setBucketPre(bucketPre);
                        item.setBucketName(bucketName);
                        item.setFilePath(downloadPath);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });

            /* 计算分页信息返回给前端 */
            PageResult pageResult = SystemUtil.parsePage(page, page1);
            return BusiResponse.OK(pageResult);
        } else {
            return BusiResponse.error("参数不正确！");
        }
    }

    @PostMapping(value = "/listAll")
    @ApiOperation(value = "双网同步-导出表功能:查询列表(不带分页)")
    public BusiResponse listAll(HttpServletRequest request) {
        QueryWrapper<SysSyncExport8357> queryWrapper = new QueryWrapper<>();
        queryWrapper.ne("del_flag", "1");
        queryWrapper.orderByDesc("create_time");
        queryWrapper.in("secret_level", SystemLoginUser.dataSecretSet);

        List<SysSyncExport8357> list = sysSyncExport8357Service.list(queryWrapper);

        list.forEach(item -> {
        });
        if (list != null && list.size() > 0) {
            return BusiResponse.OK(list);
        } else {
            return BusiResponse.ok("没有查询到数据！");
        }
    }

    @GetMapping(value = "/exportdata")
    @ApiOperation(value = "双网同步-导出表功能:导出数据")
    public BusiResponse exportdata(HttpServletRequest request) {
        // 1.插入导入记录 start
        Date currentDate = new Date();
        String exportId = IdUtils.uuid32();
        SysSyncExport8357 export = new SysSyncExport8357();
        export.setCreateTime(currentDate);
        export.setCreateUserId(SystemLoginUser.userId);
        export.setCreateUserName(SystemLoginUser.idName);
        export.setUpdateTime(currentDate);
        export.setUpdateUserId(SystemLoginUser.userId);
        export.setUpdateUserName(SystemLoginUser.idName);
        export.setExportTime(currentDate);
        export.setExportUserId(SystemLoginUser.userId);
        export.setExportUserName(SystemLoginUser.idName);
        // 导出状态:10导出文件生成中20导出文件已生成30文件已下载
        export.setExportStatus(10);
        // 导入状态10未上传20已上传 30已解压 40.数据已导入
        export.setImportStatus(10);
        export.setId(exportId);
        String encryptKey = AESUtils.getSysConfigKey();
        export.setEncryptKey(encryptKey);
        sysSyncExport8357Service.save(export);
        // 1.插入导入记录 end

        // 异步执行生成文件的操作
        asynConfig.getAsyncExecutor().execute(() -> {
            // System.out.println("======encryptKey========="+encryptKey);
            // 2.插入导入明细记录 start
            // 2.1查询配置的同步表的信息
            QueryWrapper<SysInfoSyncTable8357> tableWrapper = new QueryWrapper<>();
            tableWrapper.ne("del_flag", "1");
            // status 1需要进行同步 2不需要进行同步
            tableWrapper.eq("status", "1");
            List<SysInfoSyncTable8357> tableList = sysInfoSyncTable8357Service.list(tableWrapper);

            QueryWrapper<SysSyncExportDetail8357> exportDetailWrapper = null;
            SysSyncExportDetail8357 exportDetail = null;
            Date startDate = null;
            String sql = "";
            String tableName = "";
            StringBuffer sb = null;

            Page<Map<String, Object>> dataPage = null;
            String tempPath = getTempPathTest();
            // 导出文件保存路径
            String exportSaveDirectory = tempPath + File.separator
                    + DateUtils.formatTime(currentDate, DateUtils.YYYYMMDDHHMMSS);
            // 数据库保存路径
            String dbSaveDirectory = exportSaveDirectory + File.separator + "db";
            FileUtils.mkdirs(dbSaveDirectory);

            //todo: 正式运行时删除    调试使用， 数据库保存路径调试使用 start
            String backDirectory = exportSaveDirectory + File.separator + "back";
            FileUtils.mkdirs(backDirectory);
            //todo: 正式运行时删除    调试使用， 数据库保存路径调试使用 end

            // 原始文件保存路径
            String fileOriginalDirectory = exportSaveDirectory + File.separator + "fileoriginal";
            FileUtils.mkdirs(fileOriginalDirectory);
            //加密文件保存路径
            String fileEncryptDirectory = exportSaveDirectory + File.separator + "fileencrypt";
            FileUtils.mkdirs(fileEncryptDirectory);

            //压缩文件保存路径
            String zipDirectory = exportSaveDirectory + File.separator + "zip";
            FileUtils.mkdirs(zipDirectory);


            String updateTimeColumnType = "";
            ColumnVo updateColumn = null;
            SysSyncExportDetail8357 exportDetailToSave = null;
            String errorMsg = "";
            List<String> dbFileListToZip = new ArrayList<String>();
            String allDataString = "";
            List<String> jsonListAll = null;

            jsonListAll = new ArrayList<String>();
            String allDataEncryptString = "";
            String encryptKeySystem = encryptKey;
            List<String> dataIds = new ArrayList<String>();
            //========================10.实验表数据处理==========================================================================================
            //10.1对于导出的试验表的数据逐条导出
            tableName = ENTRUST_TEST_TABLE;

            dataPage = new Page<Map<String, Object>>(1, 200);
            sql = " select * from hf_env_test t where t.del_flag=0 and t.status=" + TestConsts.TEST_STATUS_MOVE_OUT + " and not exists( "
                    + "   select 1 from sys_sync_export_task e where e.data_id=t.id and e.del_flag=0  and e.table_name='" + ENTRUST_TEST_TABLE + "'   "
                    + " ) ";
            dataPage = mainDataSourceService.selectPage(dataPage, sql);
            updateColumn = new ColumnVo();
            updateColumn.setTableName(tableName);
            updateColumn.setPath(backDirectory);
            updateColumn.setCurrentDate(currentDate);

            // 第一页的数据处理
            writeJsonTaskData(dataPage, dbSaveDirectory, dbSaveDirectory + File.separator + tableName + DateUtils.formatTime(currentDate, DateUtils.YYYYMMDDHHMMSS) + ".txt",
                    updateColumn, jsonListAll, dataIds, "1");
            Long totalPage = dataPage.getPages();
            // 第二页开始到结束页的数据
            for (Long i = 2L; i <= totalPage; i++) {
                dataPage = new Page<Map<String, Object>>(i, 200);
                dataPage = mainDataSourceService.selectPage(dataPage, sql);
                // 2.3生成json数据，写入文件
                writeJsonTaskData(dataPage, dbSaveDirectory, dbSaveDirectory + File.separator + tableName + DateUtils.formatTime(currentDate, DateUtils.YYYYMMDDHHMMSS) + ".txt",
                        updateColumn, jsonListAll, dataIds, "1");
            }
            //10.2将当前完成的任务表的id插入到导出任务表
            SysSyncExportTask exportTask = null;
            List<SysSyncExportTask> taskToSave = new ArrayList<SysSyncExportTask>();
            for (String taskId : dataIds) {
                exportTask = new SysSyncExportTask();
                exportTask.setId(IdUtils.uuid32());
                exportTask.setDatasource(1);
                exportTask.setDataId(taskId);
                exportTask.setTableName(ENTRUST_TASK_TABLE);
                exportTask.setExportId(exportId);
                exportTask.setCreateUserId(SystemLoginUser.userId);
                exportTask.setCreateUserName(SystemLoginUser.idName);
                exportTask.setCreateTime(new Date());
                exportTask.setUpdateUserId(SystemLoginUser.userId);
                exportTask.setUpdateUserName(SystemLoginUser.idName);
                exportTask.setUpdateTime(new Date());
                taskToSave.add(exportTask);
            }
            sysSyncExportTaskService.saveBatch(taskToSave);

            allDataString = "";
            allDataEncryptString = "";
            if (jsonListAll != null && jsonListAll.size() > 0) {
                allDataString = String.join("αα", jsonListAll);
                allDataEncryptString = AESUtils.encryptString(encryptKeySystem, allDataString);
            }
            TextFileUtils.addInfoToTexTFile(dbSaveDirectory, dbSaveDirectory + File.separator + tableName + DateUtils.formatTime(currentDate, DateUtils.YYYYMMDDHHMMSS) + ".txt",
                    allDataEncryptString, false);
            dbFileListToZip.add(dbSaveDirectory + File.separator + tableName + DateUtils.formatTime(currentDate, DateUtils.YYYYMMDDHHMMSS) + ".txt");
            exportDetailToSave = new SysSyncExportDetail8357();
            exportDetailToSave.setMainId(exportId);
            exportDetailToSave.setTableName(tableName);
            // 1数据库2文件
            exportDetailToSave.setInfoType(1);
            //1主库2采集库赵赟 3第三方采集库
            exportDetailToSave.setDatasource(1);
            exportDetailToSave.setTableId("");
            exportDetailToSave.setTableDescription("");

            exportDetailToSave.setOperateEndTime(currentDate);
            // 设置导出状态为已导出
            exportDetailToSave.setExportStatus(20);
            sysSyncExportDetail8357Service.save(exportDetailToSave);

            jsonListAll = null;
            //9.任务主表的数据处理 end

//================================主库的非任务表处理=========================================================================
            //导出策略
            //3:对比create_time，4:对比update_time，5:采集表对比timestamp，6:试验主表，7:试验关联表
            String strategy = "";
            for (SysInfoSyncTable8357 tableBean : tableList) {
                if (tableBean.getTableName().equalsIgnoreCase("hf_env_gk_task")) {
                    System.out.println("=====================");
                }

                strategy = tableBean.getStrategy();
                //如果是试验表则跳过,实验表已经单独处理了
                if (tableBean.getTableName().equalsIgnoreCase(ENTRUST_TEST_TABLE)) {
                    continue;
                }
                //如果是采集库的表则跳过，采集库进行单独处理
                if (tableBean.getDatasource().equals("2")) {
                    continue;
                }

                sb = new StringBuffer();
                exportDetailWrapper = new QueryWrapper<SysSyncExportDetail8357>();
                exportDetailWrapper.ne("del_flag", "1");
                // 排除出错的信息，80表示导出出错，未导出
                exportDetailWrapper.ne("export_status", "80");
                tableName = tableBean.getTableName();
                exportDetailWrapper.eq("table_name", tableBean.getTableName());
                exportDetailWrapper.eq("info_type", "1");
                exportDetailWrapper.eq("datasource", 1);
                exportDetailWrapper.orderByDesc("operate_end_time");
                exportDetailWrapper.last("LIMIT 1");
                // 2.1查询表的明细数据，查询最后一次同步时间
                exportDetail = sysSyncExportDetail8357Service.getOne(exportDetailWrapper, false);
                if (exportDetail != null) {
                    startDate = exportDetail.getOperateEndTime();
                } else {
                    startDate = null;
                }
                updateColumn = getUpdateTimeColumnType(tableName, "update_time");

                exportDetailToSave = new SysSyncExportDetail8357();
                exportDetailToSave.setMainId(exportId);
                exportDetailToSave.setTableName(tableName);
                // 1数据库2文件
                exportDetailToSave.setInfoType(1);
                //1主库2采集库赵赟 3第三方采集库
                exportDetailToSave.setDatasource(1);
                exportDetailToSave.setTableId(tableBean.getId());
                exportDetailToSave.setTableDescription(tableBean.getDescription());

                boolean exitsColumnBySql = updateColumn.getExitsColumnBySql();
                if (!exitsColumnBySql) {
                    errorMsg = String.format("双网同步-查询表[%s]的update_time字段不存在", tableName);
                    exportDetailToSave.setExportStatus(80);
                    exportDetailToSave.setExportErrorMsg(errorMsg);
                    sysSyncExportDetail8357Service.save(exportDetailToSave);
                    log.error(errorMsg);
                    continue;
                }
                updateTimeColumnType = updateColumn.getColumnType();
                String columnJdbcType = updateColumn.getJdbcType();
                Object searchObj = null;

                // 2.2查询某个表的数据
                sb.append("select * from " + tableName + " t  where 1=1 ");
                if (startDate != null) {
                    if (columnJdbcType.equals("LONG")) {
                        sb.append("and  update_time>=" + startDate.getTime());
                    } else if (columnJdbcType.equals("DATETIME")) {
                        sb.append("and  update_time>='" + DateUtils.formatTime(startDate, DateUtils.YYYY_MM_DD_HH_MM_SS)
                                + "' ");
                    }

                }
                if (columnJdbcType.equals("LONG")) {
                    sb.append("and  update_time <" + currentDate.getTime());
                } else if (columnJdbcType.equals("DATETIME")) {
                    sb.append("and  update_time<'" + DateUtils.formatTime(currentDate, DateUtils.YYYY_MM_DD_HH_MM_SS)
                            + "' ");
                }

                if ("7".equals(strategy)) {
                    sb.append(" and  EXISTS( "
                            + "  SELECT 1 FROM sys_sync_export_task t1 WHERE t1.table_name='" + ENTRUST_TEST_TABLE + "' AND t1.data_id=t.test_id    AND t1.export_id='" + exportId + "'  "
                            + "  )   ");


                }
                sql = sb.toString();
                dataPage = new Page<Map<String, Object>>(1, 200);
                dataPage = mainDataSourceService.selectPage(dataPage, sql);
                jsonListAll = new ArrayList<String>();
                updateColumn.setPath(backDirectory);
                updateColumn.setCurrentDate(currentDate);

                // 第一页的数据处理
                writeJsonData(dataPage, dbSaveDirectory, dbSaveDirectory + File.separator + tableName + DateUtils.formatTime(currentDate, DateUtils.YYYYMMDDHHMMSS) + ".txt",
                        updateColumn, jsonListAll, "1");
                totalPage = dataPage.getPages();
                // 第二页开始到结束页的数据
                for (Long i = 2L; i <= totalPage; i++) {
                    dataPage = new Page<Map<String, Object>>(i, 200);
                    dataPage = mainDataSourceService.selectPage(dataPage, sql);

                    // 2.3生成json数据，写入文件
                    writeJsonData(dataPage, dbSaveDirectory, dbSaveDirectory + File.separator + tableName + DateUtils.formatTime(currentDate, DateUtils.YYYYMMDDHHMMSS) + ".txt",
                            updateColumn, jsonListAll, "1");
                }
                allDataString = "";
                allDataEncryptString = "";
                if (jsonListAll != null && jsonListAll.size() > 0) {
                    allDataString = String.join("αα", jsonListAll);
                    allDataEncryptString = AESUtils.encryptString(encryptKeySystem, allDataString);
                }
                TextFileUtils.addInfoToTexTFile(dbSaveDirectory, dbSaveDirectory + File.separator + tableName + DateUtils.formatTime(currentDate, DateUtils.YYYYMMDDHHMMSS) + ".txt",
                        allDataEncryptString, false);

                if (startDate != null) {
                    exportDetailToSave.setOperateStartTime(startDate);
                }
                exportDetailToSave.setOperateEndTime(currentDate);
                // 设置导出状态为已导出
                exportDetailToSave.setExportStatus(20);
                sysSyncExportDetail8357Service.save(exportDetailToSave);
                /* */
                dbFileListToZip.add(dbSaveDirectory + File.separator + tableName + DateUtils.formatTime(currentDate, DateUtils.YYYYMMDDHHMMSS) + ".txt");
            }
            // 2.插入导出明细记录 end
            //==================10采集库的文件备份=================================================================================================================================================================
            //10.采集库文件备份  start
            String schemaName = getSchemaName(collectDBUrl);


            //10.1查询所有的数据表名中有 当前年份_2025,前一年份_2024,未来一年_2026 的表
            int currentYear = DateUtils.getTime4Int(currentDate);
            int lastYear = currentYear - 1;
            int day = DateUtils.getTime8Int(currentDate) % 10000;
            String dbType = collectdbDataSourceService.getDbType();
            if (dbType.equals("mysql")) {
                //如果是年初前6天取两年的表，如果超过6天则只取当年的表
                if (day < 107) {
                    sql = " SELECT DISTINCT  table_name "
                            + "FROM information_schema.tables "
                            + "WHERE table_schema = '" + schemaName + "'  "
                            + " and (table_name like '%_" + currentYear + "%' or  table_name like '%_" + lastYear + "%') ";
                } else {
                    sql = " SELECT DISTINCT  table_name "
                            + "FROM information_schema.tables "
                            + "WHERE table_schema = '" + schemaName + "'  "
                            + " and (table_name like '%_" + currentYear + "%' ) ";
                }


            } else if (dbType.equals("dameng")) {
                if (day < 108) {
                    sql = "     SELECT  distinct  table_name  "
                            + " FROM DBA_TAB_COLUMNS t where OWNER = '" + schemaName + "' and LOWER(column_name)='timestamp' "
                            + " and (table_name like '%_" + currentYear + "%' or  table_name like '%_" + lastYear + "%') ";
                } else {
                    sql = "     SELECT  distinct  table_name  "
                            + " FROM DBA_TAB_COLUMNS t where OWNER = '" + schemaName + "' and LOWER(column_name)='timestamp' "
                            + " and (table_name like '%_" + currentYear + "%' ) ";
                }

            }


            //10.2循环所有表按照timestamp时间的时间插入数据。
            List<Map<String, Object>> collectTableList = collectdbDataSourceService.selectList(sql, null);

            for (Map<String, Object> oneMap : collectTableList) {
                tableName = StringUtils.trimNull(oneMap.get("tableName"));


                sb = new StringBuffer();
                exportDetailWrapper = new QueryWrapper<SysSyncExportDetail8357>();
                exportDetailWrapper.ne("del_flag", "1");
                // 排除出错的信息，80表示导出出错，未导出
                exportDetailWrapper.ne("export_status", "80");
                exportDetailWrapper.eq("table_name", tableName);
                exportDetailWrapper.eq("info_type", "1");
                exportDetailWrapper.eq("datasource", 2);
                exportDetailWrapper.orderByDesc("operate_end_time");
                exportDetailWrapper.last("LIMIT 1");
                // 2.1查询表的明细数据，查询最后一次同步时间
                exportDetail = sysSyncExportDetail8357Service.getOne(exportDetailWrapper, false);
                if (exportDetail != null) {
                    startDate = exportDetail.getOperateEndTime();
                } else {
                    startDate = null;
                }
                updateColumn = getTimeColumnType(tableName, "TimeStamp");

                exportDetailToSave = new SysSyncExportDetail8357();
                exportDetailToSave.setMainId(exportId);
                exportDetailToSave.setTableName(tableName);
                // 1数据库2文件
                exportDetailToSave.setInfoType(1);
                exportDetailToSave.setTableId("");
                //1主库2采集库赵赟 3第三方采集库
                exportDetailToSave.setDatasource(2);
                exportDetailToSave.setTableDescription("");


                updateTimeColumnType = "timestamp";
                String columnJdbcType = "DATETIME";
                Object searchObj = null;

                // 2.2查询某个表的数据
                sb.append("select * from " + tableName + " where 1=1 ");
                if (startDate != null) {
                    if (columnJdbcType.equals("LONG")) {
                        sb.append("and  timestamp >=" + startDate.getTime());
                    } else if (columnJdbcType.equals("DATETIME")) {
                        sb.append("and  timestamp>='" + DateUtils.formatTime(startDate, DateUtils.YYYY_MM_DD_HH_MM_SS)
                                + "' ");
                    }

                }
                if (columnJdbcType.equals("LONG")) {
                    sb.append("and  timestamp <" + currentDate.getTime());
                } else if (columnJdbcType.equals("DATETIME")) {
                    sb.append("and  timestamp<'" + DateUtils.formatTime(currentDate, DateUtils.YYYY_MM_DD_HH_MM_SS)
                            + "' ");
                }
                sql = sb.toString();
                dataPage = new Page<Map<String, Object>>(1, 200);
                dataPage = collectdbDataSourceService.selectPage(dataPage, sql);
                jsonListAll = new ArrayList<String>();
                updateColumn = new ColumnVo();
                updateColumn.setTableName(tableName);
                updateColumn.setPath(backDirectory);
                updateColumn.setCurrentDate(currentDate);
                // 第一页的数据处理
                writeJsonData(dataPage, dbSaveDirectory, dbSaveDirectory + File.separator + tableName + DateUtils.formatTime(currentDate, DateUtils.YYYYMMDDHHMMSS) + ".txt",
                        updateColumn, jsonListAll, "2");
                totalPage = dataPage.getPages();
                // 第二页开始到结束页的数据
                for (Long i = 2L; i <= totalPage; i++) {
                    dataPage = new Page<>(i, 200);
                    dataPage = collectdbDataSourceService.selectPage(dataPage, sql);

                    // 2.3生成json数据，写入文件
                    writeJsonData(dataPage, dbSaveDirectory, dbSaveDirectory + File.separator + tableName + DateUtils.formatTime(currentDate, DateUtils.YYYYMMDDHHMMSS) + ".txt",
                            updateColumn, jsonListAll, "2");
                }
                allDataString = "";
                allDataEncryptString = "";
                if (jsonListAll != null && jsonListAll.size() > 0) {
                    allDataString = String.join("αα", jsonListAll);
                    allDataEncryptString = AESUtils.encryptString(encryptKeySystem, allDataString);
                }
                TextFileUtils.addInfoToTexTFile(dbSaveDirectory, dbSaveDirectory + File.separator + tableName + DateUtils.formatTime(currentDate, DateUtils.YYYYMMDDHHMMSS) + ".txt",
                        allDataEncryptString, false);

                if (startDate != null) {
                    exportDetailToSave.setOperateStartTime(startDate);
                }
                exportDetailToSave.setOperateEndTime(currentDate);
                // 设置导出状态为已导出
                exportDetailToSave.setExportStatus(20);
                sysSyncExportDetail8357Service.save(exportDetailToSave);
                /* */
                dbFileListToZip.add(dbSaveDirectory + File.separator + tableName + DateUtils.formatTime(currentDate, DateUtils.YYYYMMDDHHMMSS) + ".txt");

            }

            //10.采集库文件备份  end
            //==================minio文件备份=================================================================================================================================================================
            //2.4生成minio文件start
            exportDetailWrapper = new QueryWrapper<SysSyncExportDetail8357>();
            exportDetailWrapper.ne("del_flag", "1");
            // 排除出错的信息，80表示导出出错，未导出
            exportDetailWrapper.ne("export_status", "80");
            exportDetailWrapper.eq("info_type", "2");
            exportDetailWrapper.orderByDesc("operate_end_time");
            exportDetailWrapper.last("LIMIT 1");
            // 2.4.1查询表的明细数据，查询最后一次同步时间 start
            exportDetail = sysSyncExportDetail8357Service.getOne(exportDetailWrapper, false);
            if (exportDetail != null) {
                startDate = exportDetail.getOperateEndTime();
            } else {
                startDate = null;
            }
            // 2.4.2查询表的明细数据，查询最后一次同步时间 end
            //2.4.3 查询base_oss_files表中需要同步的文件信息start
            //通过查询存储了文件的表名称进行数据同步


            String ossFileStorageTable;
            //查询ossFiles表的文件信息==========start

            ossFileStorageTable = "base_oss_files";
            mainDataSourceService.update("update " + ossFileStorageTable + "  set update_time=create_time where update_time is null ", null);
            exportDetailWrapper = new QueryWrapper<SysSyncExportDetail8357>();
            exportDetailWrapper.ne("del_flag", "1");
            // 排除出错的信息，80表示导出出错，未导出
            exportDetailWrapper.ne("export_status", "80");
            exportDetailWrapper.eq("table_name", ossFileStorageTable);
            exportDetailWrapper.eq("info_type", "2");
            exportDetailWrapper.orderByDesc("operate_end_time");
            exportDetailWrapper.last("LIMIT 1");

            updateColumn = getUpdateTimeColumnType(ossFileStorageTable, "update_time");

            //2.4.6 查询base_oss_files表中需要同步的文件信息end
            exportDetailToSave = new SysSyncExportDetail8357();
            exportDetailToSave.setMainId(exportId);
            exportDetailToSave.setTableName(ossFileStorageTable);
            // 1数据库2文件
            exportDetailToSave.setInfoType(2);


            updateTimeColumnType = updateColumn.getColumnType();
            String columnJdbcType = updateColumn.getJdbcType();
            Object searchObj = null;
            sb = new StringBuffer();
            // 2.4.7查询文件数据，排除同步产生的文件
            sb.append("select * from " + ossFileStorageTable + " where 1=1 and ifnull(ref_type,'') not in('hf_ts_sys_sync_export','hf_ts_sys_sync_import','sys_sync_export','sys_sync_import' )  "
                    + " and  ( ifnull(ref_type,'')  not  like 'hf_ts_%'  )    ");
            if (startDate != null) {
                if (columnJdbcType.equals("LONG")) {
                    sb.append("and  update_time>=" + startDate.getTime());
                } else if (columnJdbcType.equals("DATETIME")) {
                    sb.append("and  update_time>='" + DateUtils.formatTime(startDate, DateUtils.YYYY_MM_DD_HH_MM_SS)
                            + "' ");
                }

            }
            if (columnJdbcType.equals("LONG")) {
                sb.append("and  update_time <" + currentDate.getTime());
            } else if (columnJdbcType.equals("DATETIME")) {
                sb.append("and  update_time<'" + DateUtils.formatTime(currentDate, DateUtils.YYYY_MM_DD_HH_MM_SS)
                        + "' ");
            }
            sql = sb.toString();
            dataPage = new Page<Map<String, Object>>(1, 200);
            dataPage = mainDataSourceService.selectPage(dataPage, sql);
            //查询ossFiles表的文件信息==========end

            // 第一页的数据处理
            copyBaseOssfilesFileToLocalAndEncrypt(dataPage, fileOriginalDirectory, fileEncryptDirectory,
                    updateColumn, startDate);
            totalPage = dataPage.getPages();
            // 第二页开始到结束页的数据
            for (Long i = 2L; i <= totalPage; i++) {
                dataPage = new Page<Map<String, Object>>(i, 200);
                dataPage = mainDataSourceService.selectPage(dataPage, sql);

                // 2.3生成json数据，写入文件
                copyBaseOssfilesFileToLocalAndEncrypt(dataPage, fileOriginalDirectory, fileEncryptDirectory,
                        updateColumn, startDate);
            }
            if (startDate != null) {
                exportDetailToSave.setOperateStartTime(startDate);
            }
            exportDetailToSave.setOperateEndTime(currentDate);
            // 设置导出状态为已导出
            exportDetailToSave.setExportStatus(20);
            sysSyncExportDetail8357Service.save(exportDetailToSave);

            //2.4生成minio文件end
            //===================================================================================================================================================================================


            // 3.生成导出文件 start
            // dbFileListToZip
            String zipFilePath = "";

            // 压缩文件的最大限制 3G
            long zipFilelimitSize = (long) Math.floor(1024 * 1024 * 1024 * 3.9);
            FileParamDTO fileParam = new FileParamDTO();
            fileParam.setZipFilePrefix("filezip_" + DateUtils.formatTime(currentDate, DateUtils.YYYYMMDDHHMMSS));
            fileParam.setZipFileLimitSize(zipFilelimitSize);
            fileParam.setDealedFileSize(0);
            String destPath = exportSaveDirectory + File.separator + "zip";
            fileParam.setDestDirectory(destPath);
            fileParam.setZipFileTotalSize(0L);

            // 调用递归方法压缩文件夹
            try {
                //备份数据库
                String sourcePath = exportSaveDirectory + File.separator + "db";
                directoryToZipFile(exportSaveDirectory, sourcePath, fileParam);
                //备份文件
                sourcePath = exportSaveDirectory + File.separator + "fileencrypt";
                directoryToZipFile(exportSaveDirectory, sourcePath, fileParam);

            } catch (IOException e) {
                log.error("压缩文件报错！" + e.getMessage());
                e.printStackTrace();
            }
            if (fileParam.getZipFileList().size() > 0) {
                // 打包文件
                zipFiles(fileParam);
            }
            List<FileDTO> fileSaveToRemoteList = fileParam.getZipedFileList();
            String bucketPre = "public";
            String chartPath = UrlUtils.joinUrl("hifar/sync", DateUtils.getPathDate(currentDate));
            BaseOssFiles ossFile = null;
            for (FileDTO fileObj : fileSaveToRemoteList) {
                //System.out.println("====fileObj:======"+fileObj.getFilePath());
                try {

                    MinioUtils.uploadLocalFileToMinio(bucketPre, chartPath + "/" + fileObj.getFileName(), fileObj.getFilePath());

                    ossFile = new BaseOssFiles();
                    ossFile.setId(IdUtils.uuid32());
                    ossFile.setTenantId(SysConsts.TENANT_ID);
                    ossFile.setFileName(fileObj.getFileName());
                    ossFile.setBucketName(MinioCfgUtils.getBucketName(bucketPre));
                    ossFile.setBucketPre(bucketPre);
                    ossFile.setFilePath(chartPath + "/" + fileObj.getFileName());
                    ossFile.setFileSize(fileObj.getFileSize().doubleValue());
                    ossFile.setRefType("sys_sync_export");
                    ossFile.setRefId(exportId);
                    ossFile.setViewType("application/x-zip-compressed");
                    ossFile.setStatus(9);
                    ossFile.setChunkCount(1);
                    ossFile.setCreateTime(new Date());
                    ossFile.setCreateUserId(SystemLoginUser.userId);
                    ossFile.setCreateUserName(SystemLoginUser.idName);

                    ossFile.setUpdateTime(new Date());
                    ossFile.setUpdateUserId(SystemLoginUser.userId);
                    ossFile.setCreateUserName(SystemLoginUser.idName);
                    baseOssFilesService.save(ossFile);


                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            // 3.生成导出文件 end

            // 4.修改任务状态为完成 start
            //导出文件为多个，所有没有导出文件路径

            SysSyncExport8357 export2 = new SysSyncExport8357();
            export2.setExportStatus(20);
            export2.setUpdateTime(new Date());
            export2.setId(export.getId());
            sysSyncExport8357Service.updateById(export2);
            // 4.修改任务状态为完 end
            //5.删除多余的临时文件 start
            //deleteFileByDirectory(tempPath,tempPath, "2");
            //5.删除多余的临时文件 end
        });
        return BusiResponse.OK("导出任务添加成功");
    }

    //通过数据库url查询数据库的模式名称
    private String getSchemaName(String collectDBUrl) {
        if (collectDBUrl != null) {
            String temp = collectDBUrl.substring(0, collectDBUrl.indexOf("?"));
            temp = temp.substring(temp.lastIndexOf("/") + 1);
            return temp;
        }
        return null;
    }

    //拷贝base_oss_files表的minio文件到local目录，同时加密拷贝到加密目录
    private void copyBaseOssfilesFileToLocalAndEncrypt(Page<Map<String, Object>> page, String originalPath, String encryptPath,
                                                       ColumnVo columninfo, Date startTime) {

        String bucketName;
        String filePath;
        String fileName;


        for (Map<String, Object> dataMap : page.getRecords()) {
            bucketName = StringUtils.trimNull(dataMap.get("bucketName"));
            filePath = StringUtils.trimNull(dataMap.get("filePath"));
            fileName = StringUtils.trimNull(dataMap.get("fileName"));
            //查询minio文件是否存在，如果存在则拷贝文件，如果不存在则不处理。
            try {
                List<Item> itemList = MinioUtil.listObjects(bucketName, filePath);
                boolean fileExists = false;
                Item item = null;
                for (Item oneItem : itemList) {
                    if (oneItem.isDir() == false) {
                        item = oneItem;
                        fileExists = true;
                        break;
                    }
                }
                Date lastModify = null;
                if (fileExists) {
                    if (item.lastModified() != null) {
                        log.info("==item= zonetime:==" + item.lastModified());
                        ZonedDateTime dateTime = item.lastModified();
                        Instant instant0102 = dateTime.toInstant();
                        lastModify = Date.from(instant0102);
                        log.info("==lastModify:==" + DateUtils.formatTime(lastModify));
                    }
                }
                boolean copyFile = true;
                //ossFile的最后修改时间不在时间范围内则不进行传递
                if (fileExists) {
                    if (lastModify != null) {
                        if (startTime != null && lastModify.getTime() < startTime.getTime()) {
                            copyFile = false;
                        }
                    }
                }
                //复制文件和加密文件start
                if (copyFile) {
                    String originalFilePath = "";
                    String encryptFilePath = "";
                    originalFilePath = originalPath + File.separator + bucketName + File.separator + getPathFromMinioDirectory(filePath);
                    FileUtils.mkdirs(originalFilePath);
                    String orginalFileName = filePath.substring(filePath.lastIndexOf("/") + 1);
                    String localFilePathAndName = originalFilePath + File.separator + orginalFileName;
                    //拷贝文件到本地
                    MinioUtil.downloadFileToLocal(bucketName, filePath, localFilePathAndName);


                    //加密本地文件到加密目录
                    encryptFilePath = encryptPath + File.separator + bucketName + File.separator + getPathFromMinioDirectory(filePath);
                    String encrypFilePathAndName = encryptFilePath + File.separator + orginalFileName;
                    FileUtils.mkdirs(encryptFilePath);

                    AESUtils.encryptFile(localFilePathAndName, encrypFilePathAndName);
                }
                //复制文件和加密文件end

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


        }


    }

    private String getPathFromMinioDirectory(String filePath) {
        String retPath = "";
        if (!filePath.startsWith("/")) {
            retPath = "/" + filePath;
        }
        retPath = retPath.substring(0, retPath.lastIndexOf("/"));
        // File.separator
        if ("\\".equals(File.separator)) {
            retPath = retPath.replaceAll("/", "\\\\");
        } else {
            retPath = retPath.replaceAll("/", File.separator);
        }


        return retPath;
    }

    /*
     * 获取表的update_time字段类型，如果判断不出来，exist
     */
    private ColumnVo getUpdateTimeColumnType(String tableName, String columnName) {
        ColumnVo column = new ColumnVo();
        column.setTableName(tableName);
        Connection connection = dataSourceProp.getConnection();
        PreparedStatement preparedStatement = null;
        boolean exist = true;
        try {
            String sql = "select max(update_time) as update_time from  " + tableName
                    + "  where update_time is not null  ";
            preparedStatement = connection.prepareStatement(sql);
            ResultSet resultSet = preparedStatement.executeQuery();
            java.sql.ResultSetMetaData metaData = null;
            String columnOrginalType = "";
            String type = "";
            String jdbcType = "";
            if (resultSet != null) {
                metaData = resultSet.getMetaData();
                int columnCount = metaData.getColumnCount();
                columnOrginalType = metaData.getColumnTypeName(columnCount);
                column.setOriginalType(columnOrginalType);
                type = getTypeString(columnOrginalType);
                column.setColumnType(type);
                jdbcType = getTypeStringByJdbcType(metaData.getColumnType(columnCount));
                column.setJdbcType(jdbcType);
            }
        } catch (Exception throwables) {
            exist = false;
            throwables.printStackTrace();
            try {
                if (preparedStatement != null) {
                    preparedStatement.close();
                }
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } finally {
            try {
                if (preparedStatement != null) {
                    preparedStatement.close();
                }
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            preparedStatement = null;
            connection = null;
        }
        column.setExitsColumnBySql(exist);
        return column;
    }


    /*
     * 获取表的update_time字段类型，如果判断不出来，exist
     */
    private ColumnVo getTimeColumnType(String tableName, String columnName) {
        ColumnVo column = new ColumnVo();
        column.setTableName(tableName);
        Connection connection = dataSourceCollect.getConnection();
        PreparedStatement preparedStatement = null;
        boolean exist = true;
        try {
            String sql = "select max(" + columnName + ") as update_time from  " + tableName
                    + "  where " + columnName + " is not null  ";
            preparedStatement = connection.prepareStatement(sql);
            ResultSet resultSet = preparedStatement.executeQuery();
            java.sql.ResultSetMetaData metaData = null;
            String columnOrginalType = "";
            String type = "";
            String jdbcType = "";
            if (resultSet != null) {
                metaData = resultSet.getMetaData();
                int columnCount = metaData.getColumnCount();
                columnOrginalType = metaData.getColumnTypeName(columnCount);
                column.setOriginalType(columnOrginalType);
                type = getTypeString(columnOrginalType);
                column.setColumnType(type);
                column.setColumnName(columnName);
                jdbcType = getTypeStringByJdbcType(metaData.getColumnType(columnCount));
                column.setJdbcType(jdbcType);
            }
        } catch (Exception throwables) {
            exist = false;
            throwables.printStackTrace();
            try {
                if (preparedStatement != null) {
                    preparedStatement.close();
                }
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } finally {
            try {
                if (preparedStatement != null) {
                    preparedStatement.close();
                }
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            preparedStatement = null;
            connection = null;
        }
        column.setExitsColumnBySql(exist);
        return column;
    }

    private void writeJsonData(Page<Map<String, Object>> page, String directoryPath, String filePath,
                               ColumnVo columninfo, List<String> allList, String dataSource) {
        List<String> jsonList = new ArrayList<String>();

        Map<String, Object> fieldTypeMap = new HashMap<String, Object>();
        String dataType = "";
        boolean typeDeal = false;
        Map<String, Object> retMap = new HashMap<String, Object>();
        for (Map<String, Object> map : page.getRecords()) {
            Object obj;
            fieldTypeMap = new HashMap<String, Object>();

            for (String key : map.keySet()) {
                obj = map.get(key);
                dataType = getTypeString(obj.getClass().toString());

                changeMapValue(key, map, dataType, fieldTypeMap);
            }
            typeDeal = true;
            retMap.put("data", map);
            retMap.put("fieldType", fieldTypeMap);
            retMap.put("tableName", columninfo.getTableName());
            retMap.put("datasource", dataSource);
            jsonList.add(JsonUtils.toJson(retMap));
        }
        allList.addAll(jsonList);

        // todo: 开发完成删除代码
        String tempPath = columninfo.getPath();
        String tempfilePath = tempPath + File.separator + columninfo.getTableName() + DateUtils.formatTime(columninfo.getCurrentDate(), DateUtils.YYYYMMDDHHMMSS) + ".txt";
        TextFileUtils.addInfoToTexTFile(tempPath, tempfilePath, jsonList, true);
        // todo: 开发完成删除代码
    }

    private void writeJsonTaskData(Page<Map<String, Object>> page, String directoryPath, String filePath,
                                   ColumnVo columninfo, List<String> allList, List<String> dataIds, String dataSource) {
        List<String> jsonList = new ArrayList<String>();

        Map<String, Object> fieldTypeMap = new HashMap<String, Object>();
        String dataType = "";
        boolean typeDeal = false;
        Map<String, Object> retMap = new HashMap<String, Object>();
        String id = "";
        for (Map<String, Object> map : page.getRecords()) {

            id = StringUtils.trimNull(map.get("id"));
            dataIds.add(id);

            Object obj;
            fieldTypeMap = new HashMap<String, Object>();

            for (String key : map.keySet()) {
                obj = map.get(key);
                dataType = getTypeString(obj.getClass().toString());

                changeMapValue(key, map, dataType, fieldTypeMap);
            }
            typeDeal = true;
            retMap.put("data", map);
            retMap.put("fieldType", fieldTypeMap);
            retMap.put("tableName", columninfo.getTableName());
            retMap.put("datasource", dataSource);
            jsonList.add(JsonUtils.toJson(retMap));
        }
        allList.addAll(jsonList);

        // todo: 开发完成删除代码
        String tempPath = columninfo.getPath();
        String tempfilePath = tempPath + File.separator + columninfo.getTableName() + DateUtils.formatTime(columninfo.getCurrentDate(), DateUtils.YYYYMMDDHHMMSS) + ".txt";
        TextFileUtils.addInfoToTexTFile(tempPath, tempfilePath, jsonList, true);
        // todo: 开发完成删除代码
    }

    private void changeMapValue(String key, Map<String, Object> map, String dataType,
                                Map<String, Object> fieldTypeMap) {
        Object obj = map.get(key);
        if (dataType.equals("datatime")) {
            java.sql.Date obj1 = (java.sql.Date) obj;
            String value = DateUtils.formatTime(new Date(obj1.getTime()), DateUtils.YYYY_MM_DD_HH_MM_SS);
            map.put(key, value);
            fieldTypeMap.put(key, dataType);
        } else if (dataType.equals("localdatetime")) {
            LocalDateTime obj1 = (LocalDateTime) obj;
            ZoneId zoneId = ZoneId.systemDefault();
            ZonedDateTime zdt = obj1.atZone(zoneId);
            Date date = Date.from(zdt.toInstant());

            String value = DateUtils.formatTime(new Date(date.getTime()), DateUtils.YYYY_MM_DD_HH_MM_SS);
            map.put(key, value);
            fieldTypeMap.put(key, dataType);


        } else if (dataType.equals("date")) {
            java.sql.Date obj1 = (java.sql.Date) obj;
            String value = DateUtils.formatTime(new Date(obj1.getTime()), DateUtils.YYYY_MM_DD);
            map.put(key, value);
            fieldTypeMap.put(key, dataType);
        } else if (dataType.equals("timestamp")) {
            java.sql.Timestamp obj1 = (java.sql.Timestamp) obj;
            String value = DateUtils.formatTime(new Date(obj1.getTime()), DateUtils.YYYY_MM_DD_HH_MM_SS);
            map.put(key, value);
            fieldTypeMap.put(key, dataType);
        }

    }

    private String getTypeString(String inputString) {
        int index = inputString.lastIndexOf(".");
        String type = null;
        if (index != -1) {
            type = inputString.substring(index + 1);
        } else {
            type = inputString;
        }
        return type.toLowerCase();
    }

    @PostMapping(value = "/add")
    @ApiOperation(value = "双网同步-导出表功能:新增")
    public BusiResponse add(@RequestBody SysSyncExport8357 sysSyncExport) {
        sysSyncExport8357Service.save(sysSyncExport);
        return BusiResponse.ok("添加成功");
    }

    public static String getTypeStringByJdbcType(int type) {
        if (java.sql.Types.TINYINT == type) {
            return DataTypeConst.DATA_TYPE_TINYINT;
        } else if (java.sql.Types.SMALLINT == type) {
            return DataTypeConst.DATA_TYPE_SHORT;
        } else if (java.sql.Types.INTEGER == type) {
            return DataTypeConst.DATA_TYPE_INT;
        } else if (java.sql.Types.BIGINT == type) {
            return DataTypeConst.DATA_TYPE_LONG;
        } else if (java.sql.Types.FLOAT == type) {
            return DataTypeConst.DATA_TYPE_FLOAT;
        } else if (java.sql.Types.DOUBLE == type) {
            return DataTypeConst.DATA_TYPE_DOUBLE;
        } else if (java.sql.Types.NUMERIC == type) {
            return DataTypeConst.DATA_TYPE_DECIMAL;
        } else if (java.sql.Types.DECIMAL == type) {
            return DataTypeConst.DATA_TYPE_DECIMAL;
        } else if (java.sql.Types.DATE == type) {
            return DataTypeConst.DATA_TYPE_DATE;
        } else if (java.sql.Types.TIME == type) {
            return DataTypeConst.DATA_TYPE_DATETIME;
        } else if (java.sql.Types.TIMESTAMP == type) {
            return DataTypeConst.DATA_TYPE_DATETIME;
        } else if (java.sql.Types.BINARY == type) {
            return DataTypeConst.DATA_TYPE_BLOB;
        } else if (java.sql.Types.LONGVARBINARY == type) {
            return DataTypeConst.DATA_TYPE_BLOB;
        } else if (java.sql.Types.OTHER == type) {
            return DataTypeConst.DATA_TYPE_BLOB;
        } else if (java.sql.Types.JAVA_OBJECT == type) {
            return DataTypeConst.DATA_TYPE_BLOB;
        } else if (java.sql.Types.DISTINCT == type) {
            return DataTypeConst.DATA_TYPE_BLOB;
        } else if (java.sql.Types.STRUCT == type) {
            return DataTypeConst.DATA_TYPE_BLOB;
        } else if (java.sql.Types.ARRAY == type) {
            return DataTypeConst.DATA_TYPE_BLOB;
        } else if (java.sql.Types.BLOB == type) {
            return DataTypeConst.DATA_TYPE_BLOB;
        } else if (java.sql.Types.CLOB == type) {
            return DataTypeConst.DATA_TYPE_BLOB;
        }
        return DataTypeConst.DATA_TYPE_TEXT;
    }

    @PostMapping(value = "/edit")
    @ApiOperation(value = "双网同步-导出表功能:编辑")
    public BusiResponse edit(@RequestBody SysSyncExport8357 sysSyncExport) {
        sysSyncExport8357Service.updateById(sysSyncExport);
        return BusiResponse.ok("编辑成功！");
    }

    @GetMapping("/queryById")
    @ApiOperation(value = "双网同步-导出表功能:根据id查询数据")
    public BusiResponse queryById(@RequestParam(value = "id") String id) {
        SysSyncExport8357 byId = sysSyncExport8357Service.getById(id);
        // 查询转换附件
        return BusiResponse.OK(byId);
    }

    @GetMapping("/getNewEncryKey")
    @ApiOperation(value = "双网同步-导出表功能:获取")
    public BusiResponse getNewEncryKey(HttpServletRequest request) {
        String encryptKey = AESUtils.getNewEncryptKey();
        return BusiResponse.OK(encryptKey);
    }

    @PostMapping("/delete")
    @ApiOperation(value = "双网同步-导出表功能:逻辑删除")
    public BusiResponse delete(@RequestBody String id) {
        JSONObject jsonObject = JSON.parseObject(id);
        UpdateWrapper<SysSyncExport8357> delete = new UpdateWrapper<>();
        delete.in("id", jsonObject.getString("id").split(","));
        delete.set("del_flag", "1");
        sysSyncExport8357Service.update(delete);
        return BusiResponse.ok("删除成功！");
    }

    @PostMapping("/exportExcel")
    @ApiOperation(value = "双网同步-导出表功能:导出数据")
    public Object exportExcel(HttpServletRequest request) {
        Map<String, Object> pageInfo = RequestConver.getPageInfo(request);
        if (pageInfo == null) {
            return BusiResponse.error("参数有误！");
        }
        BusiResponse export = sysSyncExport8357Service.exportExcel(pageInfo);
        if (export.getCode() == com.hifar.fw.utils.bean.BusiConst.CODE_SUCCESS) {
            String encode = null;
            try {
                encode = URLEncoder.encode("双网同步-导出表.xlsx", "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Type", "application/vnd.ms-excel");
            headers.add("Access-Control-Expose-Headers", "Content-Disposition");
            headers.add("Content-Disposition", "filename=" + encode);
            return ResponseEntity.status(HttpStatus.OK).headers(headers).body((byte[]) export.getData());
        }
        return export;
    }

    @PostMapping("/importExcel")
    @ApiOperation(value = "双网同步-导出表功能:导入excel数据")
    public BusiResponse importExcel(@RequestParam("file") MultipartFile file) throws Exception {
        if (file.isEmpty()) {
            return BusiResponse.error("文件为空！");
        } else {
            if (ExcelTemplateUtil.isExcelFile(file)) {
                return sysSyncExport8357Service.importExcel(file);
            } else {
                return BusiResponse.error("请上传excel文件！");
            }
        }
    }


    private void deleteFileByDirectory(String fileBackupPath, String sourceFile, String fileBackUpRemainDays
    ) {
        File file = new File(sourceFile);
        String logInfo = "";
        // 如果是文件夹，则获取其内容并递归调用此方法
        if (file.isDirectory()) {
            String[] fileList = file.list();
            if (fileList != null && fileList.length > 0) {
                for (String fileName : fileList) {
                    deleteFileByDirectory(fileBackupPath, sourceFile + File.separator + fileName, fileBackUpRemainDays
                    );
                }
            } else {
                //空目录进行删除
                file.delete();
            }
            return;
        }
        String fileName = "";
        // 保留的截止时间
        Long endTime = System.currentTimeMillis() - NumberUtils.parseInt(fileBackUpRemainDays, 30) * DateUtils.DAY_LONG;
        // todo： 测试代码运行后删除
        // endTime = System.currentTimeMillis() -60*1000*2;

        fileName = file.getName();
        if (file.lastModified() < endTime) {
            file.delete();
        }
        file = null;
    }


    private static void directoryToZipFile(String path, String sourceFile, FileParamDTO fileParam) throws IOException {
        File file = new File(sourceFile);
        // 如果是文件夹，则获取其内容并递归调用此方法
        if (file.isDirectory()) {
            String[] fileList = file.list();
            if (fileList != null) {
                for (String fileName : fileList) {
                    directoryToZipFile(path, sourceFile + File.separator + fileName, fileParam);
                }
            }
            return;
        }
        Long fileSize = file.length();
        Long dealedFileSize = fileParam.getDealedFileSize();
        // 如果当前文件，超过容量限制
        if (fileSize >= fileParam.getZipFileLimitSize()) {
            // 如果存在待打包文件则打包，将该文件放入下次待打包文件列表。
            if (fileParam.getZipFileList().size() > 0) {
                // 打包文件
                zipFiles(fileParam);
            }
        } else {
            if (dealedFileSize + fileSize > fileParam.getZipFileLimitSize()) {
                if (fileParam.getZipFileList().size() > 0) {
                    // 打包文件
                    zipFiles(fileParam);
                }
            }
        }
        if (file.exists()) {
            ZipFileDTO zipFile = new ZipFileDTO();
            zipFile.setFilePath(sourceFile);
            if (sourceFile.length() > path.length()) {
                String entryName = sourceFile.substring(path.length() + 1); // 获取ZIP中的条目名称
                zipFile.setEntryName(entryName);
                // 添加到未处理的列表中
                fileParam.getZipFileList().add(zipFile);
                // 增加累计的fileSize
                fileParam.setDealedFileSize(fileParam.getDealedFileSize() + fileSize);
            }
        }

    }

    /*
     * 打包zip文件
     */
    private static void zipFiles(FileParamDTO fileParam) {

        System.out.println("=====fileParam==打包次数=====" + fileParam.getFileNameIndex());
        System.out.println("=====fileParam==打包前=====" + fileParam);
        String zipFilePrefix = fileParam.getZipFilePrefix();

        String destPath = fileParam.getDestDirectory();
        String fileName = zipFilePrefix + "_" + fileParam.getFileNameIndex() + ".zip";
        String zipFilePath = destPath + File.separator + fileName;
        FileOutputStream fos = null;
        ZipOutputStream zos = null;
        String entryName = null;
        ZipEntry zipEntry = null;
        FileInputStream fis = null;
        byte[] bytes = null;

        String logInfo = "";
        try {
            fos = new FileOutputStream(zipFilePath);
            zos = new ZipOutputStream(fos);
            for (ZipFileDTO fileDto : fileParam.getZipFileList()) {
                try {

                    logInfo = "已压缩文件:" + fileDto.getFilePath() + ",压缩开始："
                            + DateUtils.formatTime(new Date(), DateUtils.YYYY_MM_DD_HH_MM_SS);

                    log.info(logInfo);
                    fis = new FileInputStream(fileDto.getFilePath());
                    entryName = fileDto.getEntryName(); // 获取ZIP中的条目名称
                    entryName = entryName.replaceAll("\\\\", "/");
                    zipEntry = new ZipEntry(entryName);
                    zos.putNextEntry(zipEntry);

                    bytes = new byte[1024];
                    int length;
                    while ((length = fis.read(bytes)) >= 0) {
                        zos.write(bytes, 0, length);
                    }
                    logInfo = "已压缩文件:" + fileDto.getFilePath() + ",压缩结束："
                            + DateUtils.formatTime(new Date(), DateUtils.YYYY_MM_DD_HH_MM_SS);

                    log.info(logInfo);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    bytes = null;
                    if (fis != null) {
                        fis.close();
                    }
                    fis = null;
                    entryName = null;
                    zipEntry = null;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (zos != null) {
                    zos.close();
                }
                if (fos != null) {
                    fos.close();
                }
                zos = null;
                fos = null;
                entryName = null;
                zipEntry = null;
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                zos = null;
                fos = null;
                entryName = null;
                zipEntry = null;
            }
        }


        File endZipFile = new File(zipFilePath);
        Long fileSize = endZipFile.length();
        fileParam.setZipFileTotalSize(fileParam.getZipFileTotalSize() + fileSize);
        FileDTO zipedFile = new FileDTO();
        zipedFile.setFilePath(zipFilePath);
        zipedFile.setFileName(fileName);
        zipedFile.setFileSize(fileSize);
        fileParam.getZipedFileList().add(zipedFile);
        endZipFile = null;
        // 打包以后清理记录信息
        fileParam.setDealedFileSize(0);
        fileParam.setZipFileList(new ArrayList<ZipFileDTO>());
        fileParam.setFileNameIndex(fileParam.getFileNameIndex() + 1);
        // System.out.println("=====fileParam==打包后=====" + fileParam);
    }


    private static void zipFilesNew(FileParamDTO fileParam) {


        System.out.println("=====fileParam==打包次数=====" + fileParam.getFileNameIndex());
        System.out.println("=====fileParam==打包前=====" + fileParam);
        String zipFilePrefix = fileParam.getZipFilePrefix();

        String destPath = fileParam.getDestDirectory();
        String fileName = zipFilePrefix + "_" + fileParam.getFileNameIndex() + ".zip";
        String zipFilePath = destPath + File.separator + fileName;

        ZipFile zipFile = null;
        try {
            zipFile = new ZipFile(zipFilePath);
            ZipParameters zipParameters = new ZipParameters();
            // 设置压缩参数
            zipParameters.setCompressionLevel(CompressionLevel.FASTER);
            zipParameters.setCompressionMethod(CompressionMethod.DEFLATE);
            Set<String> directorySet = new HashSet<String>();


            String parentPath = "";

            for (ZipFileDTO fileDto : fileParam.getZipFileList()) {
                // 要压缩的文件目录
                File file = new File(fileDto.getFilePath());
                File parent = file.getParentFile();
                parentPath = parent.getAbsolutePath();

                if (parent.isDirectory() && !directorySet.contains(parentPath)) {
                    zipFile.addFolder(parent, zipParameters);
                    directorySet.add(parentPath);
                }

                if (file.isDirectory()) {
                    zipFile.addFolder(file, zipParameters);
                } else {
                    zipFile.addFile(file);
                }
            }

        } catch (IOException e) {
            throw new ServiceException("压缩失败!");
        } finally {
            if (zipFile != null) {
                try {
                    zipFile.close();
                } catch (IOException e) {
                }
            }
        }


    }

    //试验系统临时目录
    public static String getTempPathTest() {
        String osName = DataDealUtils.getOsName();
        if (osName.equals("linux")) {
            return "/opt/temp";
        } else if (osName.equals("win")) {
            return "c:" + File.separator + "temp";
        } else {
            return "/opt/temp";
        }
    }

    //调试系统的临时目录
    public static String getTempPathDebug() {
        String osName = DataDealUtils.getOsName();
        if (osName.equals("linux")) {
            return "/opt/tempdebug";
        } else if (osName.equals("win")) {
            return "c:" + File.separator + "tempdebug";
        } else {
            return "/opt/tempdebug";
        }
    }


}